package cate.game.role.bag.equip;


import cate.common.table.d.GDObj;
import cate.common.table.item.equip.row.EquipBaseRow;
import cate.common.table.item.equip.row.JobAttrRow;
import cate.common.table.item.hero.row.HeroBaseRow;
import cate.common.util.GameResult;
import cate.game.GameBody;
import cate.game.attr.FightAttr;
import cate.game.attr.PowerManager;
import cate.game.play.support.PlayBuildContext;
import cate.game.res.RewardShow;
import cate.game.role.Role;
import cate.game.role.bag.gem.Gem;
import cate.game.role.bag.hero.Hero;
import cate.game.role.bag.item.BaseBagItem;
import com.fasterxml.jackson.annotation.JsonIgnore;
import cp.solution.pattern.ICopiable;
import easy.java.dev.note.NoteField;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;


/**
 * 装备背包里的装备项
 */
@Getter
@Setter
public class Equip extends BaseBagItem implements ICopiable<Equip> {
    @NoteField(value = "阵营印记", detail = "如果是0说明没有")
    public byte campMark;

    @NoteField(value = "宝石数据")
    public GemsOn gemsOn;

    @NoteField(value = "注灵值")
    public int psionicExp;

    public Equip() {
    }

    public Equip(Role role, int tid, long num) {
        super(role, GDObj.Type.EQUIP, tid, num);
        initialize(role);
    }

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (gemsOn == null) {
            gemsOn = new GemsOn();
        }
        gemsOn.initialize(role);
    }

    @JsonIgnore
    public Gem getGem(String gemUid) {
        return gemsOn.getGem(gemUid);
    }

    @Override
    @JsonIgnore
    public EquipBaseRow getTpl(PlayBuildContext ctx) {
        return ctx.equipExcel().base.get(tid);
    }

    @Override
    public EquipBaseRow getTpl(GameBody game) {
        return getTpl(game.fight.getPlayBuildContext());
    }

    @Override
    public Equip copy() {
        Equip cp = new Equip();
        super.copy(cp);
        cp.campMark = this.campMark;
        if (this.gemsOn != null) {
            cp.gemsOn = this.gemsOn.copy();
        }
        cp.psionicExp = this.psionicExp;
        return cp;
    }

    /**
     * 获取装备的属性
     *
     * @param ctx  PlayBuildContext
     * @param hero 所属英雄
     */
    @JsonIgnore
    public FightAttr getEquipAttr(PlayBuildContext ctx, Hero hero) {
        FightAttr equipAttr = new FightAttr();
        EquipBaseRow row = getTpl(ctx);
        if (row == null) {
            return equipAttr;
        }
        // 装备基础属性
        equipAttr.add(new FightAttr(row.attrStr));
        //阵营印记
        if (hero != null) {
            byte camp = hero.getTpl(ctx).camp;
            if (campMark == camp) {
                equipAttr.add(new FightAttr(row.campAttrStr));
            }
        }
        return equipAttr;
    }

    /**
     * 获取装备战力
     *
     * @param ctx
     * @param hero 所属英雄
     */
    public long getEquipPoint(PlayBuildContext ctx, Hero hero) {
        return PowerManager.calcByAttr(getEquipAttr(ctx, hero), ctx);
    }

    @Override
    public String toDetail() {
        return String.format("%d", campMark);
    }

    public GameResult<Byte> onGem(PlayBuildContext ctx, Hero hero, Gem gem, byte pos) {
        return gemsOn.on(ctx, hero, pos, gem);
    }

    public GameResult<Byte> offGem(PlayBuildContext ctx, Hero hero, byte pos) {
        return gemsOn.off(ctx, hero, pos, hero != null);
    }

    public RewardShow backReward() {
        if (gemsOn != null) {
            return gemsOn.offAll(role, null, false);
        }
        return null;
    }

    public boolean hasGem() {
        return gemsOn != null && !gemsOn.gemMap.isEmpty();
    }

    //装备注灵
    public int addExp(int exp) {
        if (getTpl(role.toPlayBuildContext()) == null) {
            return exp;
        }
        int limit = getTpl(role.toPlayBuildContext()).pumpLimit;
        if (psionicExp >= limit) {
            return exp;
        }
        if (psionicExp + exp > limit) {
            int total = psionicExp + exp;
            psionicExp = limit;
            return total - limit;
        }else {
            psionicExp = psionicExp + exp;
            return 0;
        }
    }

    //装备突破
    public void breakthrough() {
        EquipBaseRow equipBaseRow = getTpl(role.toPlayBuildContext());
        if (equipBaseRow == null) {
            return;
        }
        if (equipBaseRow.breakthroughTarget == 0) {
            return;
        }
        this.psionicExp = 0;
        this.tid = equipBaseRow.breakthroughTarget;
    }

    @JsonIgnore
    public FightAttr psionicAttr(PlayBuildContext ctx, Hero hero) {
        FightAttr equipAttr = new FightAttr();
        EquipBaseRow row = getTpl(ctx);
        if (row == null) {
            return equipAttr;
        }
        if (row.canPump != 1) {
            return equipAttr;
        }
        double percent;
        if (psionicExp >= row.pumpLimit) {
            percent = 1.0;
        }else {
            percent = ((double) psionicExp) / row.pumpLimit;
        }
        // 装备注灵属性
        equipAttr.add(new FightAttr(row.pumpAttrStr).scale(percent));
        //装备职业属性
        if (hero != null) {
            HeroBaseRow heroBaseRow = hero.getTpl(ctx);
            if (heroBaseRow == null) {
                return equipAttr;
            }
            JobAttrRow jobAttrRow = ctx.equipExcel().jobAttr.get(this.tid);
            if (jobAttrRow == null) {
                return equipAttr;
            }
            String attr = jobAttrRow.getAttrByJob(heroBaseRow.job);
            if (StringUtils.isNotBlank(attr)) {
                equipAttr.add(new FightAttr(attr));
            }
        }
        return equipAttr;
    }

    @JsonIgnore
    public int consumeExp() {
        EquipBaseRow tpl = getTpl(role.toPlayBuildContext());
        if (tpl == null) {
            return 0;
        }
        return tpl.pumpValue;
    }

    @Override
    public boolean unique() {
        return hasGem();
    }
}
